<?php namespace App\Repositories\Eloquent\Item;

use App\Exceptions\Item\ItemException;
use App\Exceptions\OtherException;
use App\Models\Item;
use App\Models\ItemExtend;
use App\Models\ItemHasContact;
use App\Repositories\Eloquent\Item\Entity\ItemEntity;
use App\Repositories\Item\ItemRepositoryInterface;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class ItemRepository implements ItemRepositoryInterface
{
    /**
     * 查询消息
     *
     * @param $id
     *
     * @return \Illuminate\Database\Eloquent\Collection|\App\Models\Item|\App\Models\Item[]
     */
    public function show($id)
    {
        return Item::query()->find($id);
    }

    /**
     * 查询消息，如果查询不到，这抛出异常
     *
     * @param $id
     *
     * @return \Illuminate\Database\Eloquent\Collection|\App\Models\Item|\App\Models\Item[]
     * @throws ItemException
     */
    public function showWitThrow($id)
    {
        try {
            return Item::query()->findOrFail($id);
        } catch (ModelNotFoundException $e) {
            throw new ItemException(ItemException::NOT_FOUND);
        }
    }

    /**
     * 发布者的信息列表
     *
     * @param $publisher_uid
     * @param $per_page
     *
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getPublisherItems($publisher_uid, $per_page)
    {
        return Item::query()
            ->where('publisher_uid', $publisher_uid)
            ->orderBy('created_at', 'desc')
            ->paginate($per_page);
    }

    /**
     * 新增信息
     *
     * @param ItemEntity $entity
     *
     * @return Item
     * @throws OtherException
     */
    public function store(ItemEntity $entity)
    {
        $bool = $this->checkItemTitleRepeat($entity->title, $entity->company_id, $entity->project_id);
        throw_if($bool, new OtherException('信息标题重复'));

        $model = new Item();
        $model->fill($entity->toArray());
        $model->status = Item::STATUS_VALID;
        throw_unless($model->save(), new OtherException('信息发布失败，请重试!'));

        $model->extend()->save(new ItemExtend([
            'description' => $entity->description,
        ]));

        $contact_model = new ItemHasContact([
            'name'  => $entity->contact_name,
            'phone' => $entity->contact_phone,
        ]);
        $model->contact()->save($contact_model);

        $model->tags()->sync($entity->tag_ids);

        return $model;
    }

    /**
     * 修改信息
     *
     * @param            $id
     * @param ItemEntity $entity
     *
     * @return Item
     * @throws OtherException
     */
    public function update($id, ItemEntity $entity)
    {
        throw_unless($this->isMyItem($entity->publisher_uid, (int)$id), new OtherException('没有权限修改'));

        throw_if(
            $this->checkItemTitleRepeat($entity->title, $entity->company_id, $entity->project_id, $id),
            new OtherException('信息标题重复')
        );

        $item = $this->show((int)$id);
        $item->find(array_except($entity->toArray(), 'status'));
        throw_unless($item->save(), new OtherException('信息修改失败，请重试!'));

        $item->extend()->update(['description' => $entity->description]);

        /** @var ItemHasContact $contact */
        $contact = $item->contact;
        //修改联系人
        if (!$contact || $contact->name != $entity->contact_name || $contact->phone != $entity->contact_phone) {
            if ($contact) {
                $contact->delete();
            }

            $item->contact()->save(new ItemHasContact([
                'name'  => $entity->contact_name,
                'phone' => $entity->contact_phone,
            ]));
        }

        $item->tags()->sync($entity->tag_ids);

        return $item;
    }

    /**
     * 发布者结束掉信息
     *
     * @param $id
     * @param $user_id
     *
     * @return Item|Item[]|\Illuminate\Database\Eloquent\Collection
     */
    public function publisherFinish($id, $user_id)
    {
        throw_unless($this->isMyItem($user_id, (int)$id), new OtherException('没有权限修改'));

        $item = $this->show($id);
        throw_unless($item->isValid(), new OtherException('无效状态'));

        $item->status = Item::STATUS_FINISH;
        throw_unless($item->save(), new OtherException('信息修改失败，请重试!'));

        return $item;
    }

    /**
     * 是否自己的信息
     *
     * @param $publisher_uid
     * @param $id
     *
     * @return bool
     */
    private function isMyItem($publisher_uid, $id)
    {
        return Item::query()->where(compact('publisher_uid', 'id'))->count() > 0;
    }

    /**
     * 判断信息表标题是否重复
     *
     * @param      $title
     * @param      $company_id
     * @param      $project_id
     * @param null $unless_id
     *
     * @return bool
     */
    private function checkItemTitleRepeat($title, $company_id, $project_id, $unless_id = null)
    {
        $query = Item::query();

        if (isset($unless_id)) {
            $query->where('id', '<>', $unless_id);
        }

        return $query->where(compact('title', 'company_id', 'project_id'))
                ->count() > 0;
    }

    /**
     * 最新有效信息
     *
     * @param $per_page
     *
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function latestValidItems($per_page)
    {
        return Item::query()
            ->where('status', Item::STATUS_VALID)
            ->latest()
            ->paginate($per_page);
    }

}
